using System;
using System.Collections.Generic;
using System.Text;
using Weazel.Microblaze.Simulator.Engine;
using Weazel.Microblaze.Simulator.Components.Opb;

namespace Weazel.Microblaze.Simulator.Components.OpbUartLite
{
    public class OpbUartLite : OpbSlaveBase
    {
        private Rs232ConsoleForm form;

        private System.IO.TextWriter writer;
        private Simulator.Engine.SimulationContext simulator;

        public override void Load(byte[] bytes, uint address)
        {
            throw new NotSupportedException();
        }

        public OpbUartLite(Simulator.Engine.SimulationContext simulator, uint low, uint high)
            : base(simulator)
        {
            this.HighAddress = high;
            this.LowAddress = low;

            this.simulator = simulator;

            if (simulator.ConsoleOutputWriter == null)
            {
                form = new Rs232ConsoleForm();
                form.Show();
            }
        }

        public override string GetStatusString()
        {
            return "n/a";
        }

        public override void Run()
        {
            while (true)
                WaitClock();
        }

        public override void CleanUp()
        {
            if (form != null)
                form.Close();
        }

        public override void BeginTransaction(Transaction transaction)
        {
            if (transaction.Type == Transaction.TransactionType.Read)
            {
                if (transaction.Address == LowAddress + 0)
                {
                    // read from receive FIFO
                    throw new Exception();
                }
                else if (transaction.Address == LowAddress + 8)
                {
                    // read from status register

                    transaction.Value = 4; // transmit fifo is empty ..
                }
                else
                {
                    throw new NotSupportedException("RS232 address out of range");
                }
            }
            else if (transaction.Type == Transaction.TransactionType.Write)
            {
                if (form != null)
                    form.ConsoleControl.AppendCharacter((char)transaction.Value);

                if (simulator.ConsoleOutputWriter != null)
                    simulator.ConsoleOutputWriter.Write((char)transaction.Value);
            }

            transaction.Status = Transaction.TransactionStatus.Complete;
        }
    }
}
